//! @file   lc_atomic_word.h
//! @brief  
//! @author Sayan Chaliha
//! @date   September, 2011
//!
//! 
#ifndef _LC_ATOMIC_WORD_H
#define _LC_ATOMIC_WORD_H

#include "libcyan_internal.h"
#include "lc_types.h"
#include "lc_object.h"
#include "lc_multi_reader_lock.h"

namespace cyan {    
  class CYAN_API AtomicWord : public Object {
  public:
    AtomicWord();
    AtomicWord(Int32 value);
    AtomicWord(const AtomicWord& source);
    virtual ~AtomicWord();

    AtomicWord&  operator =(Int32 source);
    AtomicWord&  operator =(const AtomicWord& source);

    inline void    increment();
    inline void    decrement();
    AtomicWord&    operator ++();
    AtomicWord&    operator --();
    AtomicWord     operator ++(Int);
    AtomicWord     operator --(Int);

    void           add(Int32 value);
    void           set(Int32 value);

    virtual UInt32 hashCode() const;

    Bool    operator ==(Int32 value)                   const;
    Bool    operator ==(const AtomicWord& atomicWord)  const;
    Bool    operator !=(Int32 value)                   const;
    Bool    operator !=(const AtomicWord& atomicWord)  const;
    Bool    operator <=(Int32 value)                   const;
    Bool    operator <=(const AtomicWord& atomicWord)  const;
    Bool    operator >=(Int32 value)                   const;
    Bool    operator >=(const AtomicWord& atomicWord)  const;
    Bool    operator <(Int32 value)                    const;
    Bool    operator <(const AtomicWord& atomicWord)   const;
    Bool    operator >(Int32 value)                    const;
    Bool    operator >(const AtomicWord& atomicWord)   const;

  private:
    Int32 CYAN_HIDDEN   atomicFetchAndAdd(Int32 value);

    friend Bool   operator ==(Int32 lhs, const AtomicWord& rhs);
    friend Bool   operator !=(Int32 lhs, const AtomicWord& rhs);
    friend Bool   operator <=(Int32 lhs, const AtomicWord& rhs);
    friend Bool   operator >=(Int32 lhs, const AtomicWord& rhs);
    friend Bool   operator <(Int32 lhs, const AtomicWord& rhs);
    friend Bool   operator >(Int32 lhs, const AtomicWord& rhs);

    internal::_lc_AtomicWord  data_;

#ifndef LC_ATOMIC_BUILTINS
    mutable MultiReaderLock guard_;
#endif /* LC_ATOMIC_BUILTINS */
  };

  Bool    CYAN_API   operator ==(Int32 lhs, const AtomicWord& rhs);
  Bool    CYAN_API   operator !=(Int32 lhs, const AtomicWord& rhs);
  Bool    CYAN_API   operator <=(Int32 lhs, const AtomicWord& rhs);
  Bool    CYAN_API   operator >=(Int32 lhs, const AtomicWord& rhs);
  Bool    CYAN_API   operator <(Int32 lhs, const AtomicWord& rhs);
  Bool    CYAN_API   operator >(Int32 lhs, const AtomicWord& rhs);
}

#endif /* _LC_ATOMIC_WORD_H */
